<?php
namespace App\Goods\Services;

use App\BaseService;
use App\Clinic\Models\Clinic;
use App\Goods\Models\Goods;
use App\Goods\Models\GoodsBase;
use App\Goods\Models\GoodsStock;
use App\Goods\Models\GoodsStockLog;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;

class GoodsStockService extends BaseService {

    /**
     * User: zhangchaoqun
     * DateTime: 2021/6/25 11:11 上午
     * Describe: 解冻库存操作
     * Version: V1.0
     * @param int $clinicId 诊所ID
     * @param int $baseId 商品基本信息表ID
     * @param int $unfreezeNum 解冻库存数量
     * @param false $back 是否解冻之后回退到库存数量 默认false不回退 true则回退
     */
    public function unfreezeStock(int $clinicId, int $baseId, int $unfreezeNum, $back = false)
    {
        $goodsStockData = GoodsStock::where('clinic_id', '=', $clinicId)->where('base_id', '=', $baseId)->first();
        if (!$goodsStockData) {
            throw new \Exception('库存记录不存在，请先核实');
        }

        // 解冻库存时需要加锁避免错误操作库存
        $cacheLock = Cache::lock('UNFREEZE_STOCK_' . $goodsStockData->id);
        if (!$cacheLock->get()) {
            throw new \Exception('库存解冻系统繁忙，请稍后尝试');
        }

        try {
            if ($goodsStockData->freeze_stock < $unfreezeNum) {
                throw new \Exception('解冻库存数量与库存冻结数量不相符，请核实');
            }

            $stock = $back ? $goodsStockData->stock + $unfreezeNum : $goodsStockData->stock;
            $freezeStock = $goodsStockData->freeze_stock - $unfreezeNum;
            $state = GoodsStock::where('id', '=', $goodsStockData->id)->update([
                'stock' => $stock,
                'freeze_stock' => $freezeStock
            ]);
            if (!$state) {
                throw new \Exception('解冻库存操作失败，请联系客服人员');
            }

            // 释放REDIS锁
            $cacheLock->release();
        } catch (\Exception $exception) {
            // 释放REDIS锁
            $cacheLock->release();

            throw new \Exception($exception->getMessage());
        }
    }

    /**
     * User: zhangchaoqun
     * DateTime: 2021/6/25 10:57 上午
     * Describe: 冻结库存操作
     * Version: V1.0
     * @param int $clinicId 诊所ID
     * @param int $baseId 商品基本信息表ID
     * @param int $freezeNum 冻结数量
     */
    public function freezeStock(int $clinicId, int $baseId, int $freezeNum)
    {

        $goodsStockData = GoodsStock::where('clinic_id', '=', $clinicId)->where('base_id', '=', $baseId)->first();
        if (!$goodsStockData) {
            throw new \Exception('库存记录不存在，请先录入库存');
        }

        // 冻结库存时需要加锁避免错误操作库存
        $cacheLock = Cache::lock('FREEZE_STOCK_' . $goodsStockData->id);
        if (!$cacheLock->get()) {
            throw new \Exception('库存冻结系统繁忙，请稍后尝试');
        }

        try {
            if ($goodsStockData->stock < $freezeNum) {
                throw new \Exception("商品SKU：$goodsStockData->sku 仅存库存数量 $goodsStockData->stock ,库存不足无法冻结！");
            }

            $state = GoodsStock::where('id', '=', $goodsStockData->id)->update([
                'stock' => DB::raw("stock - $freezeNum"),
                'freeze_stock' => DB::raw("freeze_stock + $freezeNum")
            ]);
            if (!$state) {
                throw new \Exception('冻结库存操作失败，请联系客服人员');
            }

            // 释放REDIS锁
            $cacheLock->release();
        } catch (\Exception $exception) {
            // 释放REDIS锁
            $cacheLock->release();

            throw new \Exception($exception->getMessage());
        }
    }

    /**
     * User: zhangchaoqun
     * DateTime: 2021/6/25 10:26 上午
     * Describe: 添加商品库存 添加商品时调用此SERVICE
     * Version: V1.0
     * @param int $clinicId 诊所ID
     * @param int $baseId 商品基本信息表ID
     * @param string $sku 商品SKU
     * @param float $price 零售价
     * @param float $costPrice 成本价
     * @param int $stock 库存
     */
    public function addStock(int $clinicId, int $baseId, string $sku, float $price, float $costPrice, int $stock)
    {
        // 校验诊所信息
        $clinicData = Clinic::find($clinicId);
        if (!$clinicData) {
            throw new \Exception('诊所信息不存在，请核实');
        }

        // 校验商品基本信息是否存在
        $goodsBaseData = GoodsBase::where('id', '=', $baseId)->where('sku', '=', $sku)->first();
        if (!$goodsBaseData) {
            throw new \Exception('商品基本信息不存在，请核实');
        }

        // 校验是否已存在诊所对应的SKU商品
        $goodsStockData = GoodsStock::where('clinic_id', '=', $clinicId)->where('sku_sn', '=', $sku)->first();
        if ($goodsStockData) {
            $state = GoodsStock::where('id', '=', $goodsStockData->id)->update([
                'price' => $price,
                'cost_price' => $costPrice,
                'stock' => DB::raw("stock + $stock")
            ]);

            if (!$state) {
                throw new \Exception('更新库存操作失败');
            }
        } else {
            $goodsStock = GoodsStock::create([
                'clinic_id' => $clinicId,
                'base_id' => $baseId,
                'sku_sn' => $sku,
                'price' => $price,
                'cost_price' => $costPrice,
                'stock' => $stock
            ]);

            if (!$goodsStock) {
                throw new \Exception('新增库存操作失败');
            }
        }
    }
}
